#ifndef __THREAD_THREAD_H
#define __THREAD_THREAD_H

#include "../lib/stdint.h"

#define GET_TASK_STRUCT(ts) asm volatile ("movl %%esp, %0":"=g"(ts)::"memory")

typedef void thread_func(void *);

enum task_status
{
	RUNNING,
	READY,
	WAITING,
	HANGING,
	DIED
};

struct intr_stack
{
	uint32_t vec_no;
	uint32_t edi;
	uint32_t esi;
	uint32_t ebp;
	uint32_t esp_dummy;
	uint32_t ebx;
	uint32_t edx;
	uint32_t ecx;
	uint32_t eax;
	uint32_t gs;
	uint32_t fs;
	uint32_t es;
	uint32_t ds;
	uint32_t error_code;
	void (*eip) (void);
	uint32_t cs;
	uint32_t eflags;
	void *esp;
	uint32_t ss;
};

struct thread_stack
{
	uint32_t ebp;
	uint32_t ebx;
	uint32_t edi;
	uint32_t esi;

	void (*eip)(thread_func * function, void * args);//Enter this function use ret.
	void (*ret);								 //Placeholder.
	thread_func * function;
	void * args;
};

struct task_struct
{
	uint32_t * kstack;
	enum task_status status;
	uint8_t priority;
	char name[16];
	uint32_t ticks;
	uint32_t elapsed_ticks;
	uint32_t * pgdir;
	struct task_struct *next;
	struct task_struct *prev;
	uint32_t kstack_magic;
};

struct tasks_list
{
	struct task_struct * head;
	struct task_struct * tail;
};

struct task_struct * run_thread(const char * name, int prio, thread_func * func, void * args);
void schedule();
void switch_task(struct task_struct * next, struct task_struct * current);
void main_thread();



#endif

